﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.ComponentModel;

namespace ScreenReaderAPIWrapper
{
    public class ScreenReader : IScreenReader
    {
        [DllImport("Lib\\ScreenReaderApi.dll")]
        private static extern bool sayString([MarshalAs(UnmanagedType.LPStr)]string stringToSay, bool interrupt);

        [DllImport("Lib\\ScreenReaderApi.dll")]
        private static extern bool stopSpeech();

        [DllImport("Lib\\ScreenReaderApi.dll")]
        private static extern int getCurrentScreenReader();

        [DllImport("Lib\\ScreenReaderApi.dll")]
        private static extern bool setCurrentScreenReader(int sr);

        [DllImport("Lib\\ScreenReaderApi.dll")]
        private static extern string getCurrentScreenReaderName();

        [DllImport("Lib\\ScreenReaderApi.dll")]
        private static extern int setScreenReaderName([MarshalAs(UnmanagedType.LPStr)]string name);

        [DllImport("Lib\\ScreenReaderApi.dll")]
        private static extern bool sapiIsEnabled();

        [DllImport("Lib\\ScreenReaderApi.dll")]
        private static extern bool sapiEnable(bool enable);

        [DllImport("Lib\\ScreenReaderApi.dll")]
        private static extern bool sapiSayString([MarshalAs(UnmanagedType.LPStr)]string stringToSay, bool interrupt);

        [DllImport("Lib\\ScreenReaderApi.dll")]
        private static extern bool sapiSetRate(int rate);

        [DllImport("Lib\\ScreenReaderApi.dll")]
        private static extern int sapiGetRate();
        
        /// <summary>
        /// Reads the given string, interrupting any currently speaking strings
        /// </summary>
        /// <param name="stringToSay">The text to be read aloud </param>
        public void SayString(string stringToSay)
        {
            SayString(stringToSay, true);
        }

        /// <summary>
        /// Reads the given string and optionally will interrupt any currently reading text
        /// </summary>
        /// <param name="stringToSay">The string to be read aloud</param>
        /// <param name="isInterrupt">Whether to interrupt currently reading text</param>
        public void SayString(string stringToSay, bool isInterrupt)
        {
            sayString(stringToSay, isInterrupt);
        }

        /// <summary>
        /// Speaks the given message using SAPI, interrupting any currently reading SAPI speech
        /// </summary>
        /// <param name="stringToSay">The string to be read aloud</param>
        public void SAPISayString(string stringToSay)
        {
            SAPISayString(stringToSay, true);
        }

        /// <summary>
        /// Reads the given message with SAPI, optionally interrupting currently reading SAPI speech
        /// </summary>
        /// <param name="stringToSay">The string to be read aloud</param>
        /// <param name="isInterrupt">Whether to interrupt currently reading messages</param>
        public void SAPISayString(string stringToSay, bool isInterrupt)
        {
            sapiSayString(stringToSay, isInterrupt);
        }
        
        /// <summary>
        /// Stops the screenreader speaking and returns true or false depending on success
        /// </summary>
        public bool StopSpeech()
        {
            return stopSpeech();
        }

        /// <summary>
        /// Gets or sets the integer representation of the current screen reader
        /// </summary>
        public int ScreenReaderNumber
        {
            get { return getCurrentScreenReader(); }
            set { setCurrentScreenReader(value); }
        }
        
        /// <summary>
        /// Gets or sets the name of the currently running screen reader
        /// </summary>
        public string ScreenReaderName
        {
            get { return getCurrentScreenReaderName(); }
            set { setScreenReaderName(value); }
        }
        
        /// <summary>
        /// Gets or sets whether Sapi will speak in the absense of a screenreader running
        /// </summary>
        public bool SapiEnabled
        {
            get { return sapiIsEnabled(); }
            set { sapiEnable(value); }
        }

        /// <summary>
        /// Gets or sets the Sapi rate. 
        /// </summary>
        /// <remarks>Setting will be restricted to values between 0 and 100</remarks>
        public int SapiRate
        {
            get { return sapiGetRate(); }
            set
            {
                if (value < 0)
                {
                    value = 0;
                }
                else if (value > 100)
                {
                    value = 100;
                }
                sapiSetRate(value);
            }
        }

    }
}